/**
 * @file Define the errors used in application
 * 
 * @author Steve Gao<gaofu@parllay.com>
 */

/**
 * The application error class
 * 
 * @class ApplicationError
 * @param {String} message - The error message
 * @param {String} errno - The error number
 * @extends {Error}
 */
class ApplicationError extends Error {

    get errno() {
        return this._errno;
    }
    
    constructor(message, errno) {
        super(message);
        this._errno = errno;
    }

    toString() {
        return super.toString() + "\nError No: " + this.errno + "\n";
    }
}

exports.ApplicationError = ApplicationError;

/**
 * Define the wechat error
 * 
 * @class WeChatError
 * @param {String} message - The error message
 * @param {String} errno - The error number
 * @param {Object} wechatContext - The wechat context information
 * 
 * @extends {ApplicationError}
 */
class WeChatError extends ApplicationError {

    get name() {
        return 'WeChatError';
    }

    get Context() {
        return this._wechatContext;
    }

    constructor(message, errno, wechatContext) {
        super(message, errno);
        this._wechatContext = wechatContext;
    }

    toString() {
        return super.toString() + "\nContext: " + JSON.stringify(this.Context);
    }
}

exports.WeChatError = WeChatError;

/**
 * Define the MySQL error
 * 
 * @class MySQLError
 * @param {String} message - The error message
 * @param {String} errno - The error number
 * @param {Object} mysqlContext - The MySQL context information
 * 
 * @extends {ApplicationError}
 */
class MySQLError extends ApplicationError {
    get name() {
        return 'MySQLError';
    }

    get Context() {
        return this._mysqlContext;
    }

    constructor(message, errno, mysqlContext) {
        super(message, errno);
        this._mysqlContext = mysqlContext;
    }

    toString() {
        return super.toString() + "\nContext: " + JSON.stringify(this.Context);
    }
}

exports.MySQLError = MySQLError;

/**
 * Define the Redis error
 * 
 * @class RedisError
 * @param {String} message - The error message
 * @param {String} errno - The error number
 * @param {Object} redisContext - The Redis context information
 * 
 * @extends {ApplicationError}
 */
class RedisError extends ApplicationError {
    get name() {
        return 'RedisError';
    }

    get Context() {
        return this._redisContext;
    }

    constructor(message, errno, redisContext) {
        super(message, errno);
        this._redisContext = redisContext;
    }

    toString() {
        return super.toString() + "\nContext: " + JSON.stringify(this.Context);
    }
}

exports.RedisError = RedisError;

/**
 * The Web Request Error class
 * 
 * @class WebRequestError
 * @param {String} message - The error message
 * @param {String} errno - The error number
 * @param {Object} requestContext - The request context
 * @extends {ApplicationError}
 */
class WebRequestError extends ApplicationError {
    get name() {
        return 'WebRequestError';
    }

    get requestContext() {
        return this._requestContext;
    }

    constructor(message, errno, requestContext) {
        super(message, errno);
        this._requestContext = requestContext;
    }

    toString() {
        return super.toString() + "\nContext: " + JSON.stringify(this.requestContext);
    }
}

exports.WebRequestError = WebRequestError;